#include<iostream>
#include<cstdio>
#include<string>
#include<Winsock2.h>
#include<ctime>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
#define MAX_BUFSIZE 1024
char name[5];
char recvBuf[MAX_BUFSIZE];
char sendBuf[MAX_BUFSIZE];
bool connected = false;
char* curTime() {
	time_t t = time(0);
	return ctime(&t);
}
//收消息
DWORD WINAPI receiver(LPVOID lpParameter) {
	SOCKET* socketClient = (SOCKET*)(LPVOID)lpParameter;
	while (true) {
		if (recv(*socketClient, recvBuf, sizeof(recvBuf), 0) > 0) {
			//收到Server收到/exit的通知
			if (!strcmp(recvBuf, "/exitok\n")) {
				cout << "[System] Connection to server closed\n";
				connected = false;
				return 0;
			}
			string recvMsg = recvBuf;
			char serverTimeStr[11];
			strcpy(serverTimeStr, recvMsg.substr(4, 10).c_str());
			serverTimeStr[10] = 0;
			time_t serverTimeVal = atoi(serverTimeStr);
			char* sendTime = ctime(&serverTimeVal);
			string sendTimeStr = sendTime;
			sendTimeStr[sendTimeStr.length() - 1] = 0;
			cout << recvMsg.substr(0, 4) << " ------- " << sendTimeStr << " >>>>> " << curTime() << recvMsg.substr(14) << endl;
		}
		else {
			if (WSAGetLastError() == 10054) {//Server关闭连接（非Client关闭）
				cout << "[System] Lost connection with server\n";
				return 0;
			}
			else {
				if (WSAGetLastError() == 10038) {	//断联
					break;
				}
				cout << "[System] Unsuccessful Receiving with exit code " << WSAGetLastError() << endl;
			}
		}
		memset(recvBuf, 0, sizeof(recvBuf));
	}
}

int main() {
	//###初始化
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData)) {
		cout << "[System] WSAStartup failed\n";
	}
	//###客户端Socket
	SOCKET* socketClient = new SOCKET;
	*socketClient = socket(AF_INET, SOCK_STREAM, 0);
	//###设置地址信息
	char ip[17];
	cout << "[System] Input Server IP: \n";
	cin >> ip;
	int u[4] = { 0 };
	char* tokenPtr = strtok(ip, ".");
	int i = 0;
	while (tokenPtr != nullptr && i < 4) {
		u[i] = strtol(tokenPtr, 0, 10);
		tokenPtr = strtok(NULL, ".");
		i++;
	}
	int port = 8000;
	cout << "[System] Input Server Port: \n";
	cin >> port;
	SOCKADDR_IN addrServer;
	addrServer.sin_family = AF_INET;//ipv4
	addrServer.sin_addr.S_un.S_addr = (u[3] << 24) | (u[2] << 16) | (u[1] << 8) | u[0];//ip
	addrServer.sin_port = htons(port);//端口信息
	//###连接
	if (connect(*socketClient, (LPSOCKADDR)&addrServer, sizeof(addrServer))) {
		cout << "[System] Connection failure\n";
		return -1;
	}
	connected = true;
	cout << "[System] Connected to Server " << inet_ntoa(addrServer.sin_addr) << ": " << ntohs(addrServer.sin_port) << endl;
	if (recv(*socketClient, name, sizeof(name), 0) > 0) {
		cout << "Your user name is " << name << endl;
	}
	else {
		cout << "Unsuccessfully received name.\n";
	}
	//###发消息
	char timeBuf[11];	//发送时间信息
	char inputBuf[MAX_BUFSIZE - 14];	//聊天信息
	char c[1];
	cin.getline(c, 1); //处理cin末尾0字符
	HANDLE hThread = CreateThread(NULL, NULL, &receiver, (LPVOID)socketClient, 0, NULL);
	while (connected) {
		//cout << "############### Start Input ###############\n";
		cin.getline(inputBuf, MAX_BUFSIZE - 10);
		//cout << "############### End Input #################\n";
		time_t curTimeVal = time(0);
		string curTimeStr = to_string(curTimeVal);
		strcpy(timeBuf, curTimeStr.c_str());
		sprintf(sendBuf, "%s%s%s", name, timeBuf, inputBuf);
		if (send(*socketClient, sendBuf, sizeof(sendBuf), 0) < 0) {
			if (WSAGetLastError() == 10054) {//Server关闭连接（非Client关闭）
				cout << "[System] Lost connection with server " << inet_ntoa(addrServer.sin_addr) << ": " << ntohs(addrServer.sin_port) << endl;
				return 0;
			}
			else {
				if (WSAGetLastError() == 10038) {	//断联
					break;
				}
				cout << "[System] Unsuccessful Sending with exit code " << WSAGetLastError() << endl;
			}
		}
		memset(sendBuf, 0, sizeof(sendBuf));
		Sleep(1000);
	}
	CloseHandle(hThread);
	closesocket(*socketClient);
	WSACleanup();
	return 0;
}